package com.sgai.zero_robot.utils;

import android.annotation.SuppressLint;

import java.util.ArrayDeque;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class ThreadPoolUtils {
    //系统最大可用线程
    private static final int CPU_AVAILABLE = Runtime.getRuntime().availableProcessors();
    //核心线程数
    private static final int CORE_POOL_SIZE = CPU_AVAILABLE + 1;
    //最大线程数
    private static final int MAX_POOL_COUNTS = CPU_AVAILABLE * 2 + 1;
    //线程存活时间
    private static final long KEEP_ALIVE_TIME = 1L;
    //队列长度
    private static final int QUEUE_CAPACITY = 128;

    private static final ThreadPoolUtils INSTANCE = new ThreadPoolUtils();

    public static ThreadPoolUtils getInstance() {
        return INSTANCE;
    }
    private Runnable activeTask;
    private ThreadPoolExecutor threadPoolExecutor;
    private final BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(QUEUE_CAPACITY);
    private final ArrayDeque<Runnable> serialTaskQueue = new ArrayDeque<>();
    private final Object lock = new Object();

    private ThreadPoolUtils() {
        threadPoolExecutor = new ThreadPoolExecutor(
                CORE_POOL_SIZE,
                MAX_POOL_COUNTS,
                KEEP_ALIVE_TIME,
                TimeUnit.SECONDS,
                workQueue,
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }

    /**
     * 添加并行任务
     * @param task
     */
    public void addParallelTask(Runnable task) {
        if (task == null) {
            throw new NullPointerException("Parallel task cannot be null");
        }

        ThreadPoolExecutor executor;
        synchronized (lock) {
            executor = threadPoolExecutor;
            if (executor == null || executor.isShutdown()) {
                throw new IllegalStateException("ThreadPool has been shutdown");
            }
        }
        executor.execute(task);
        logPoolStatus(executor);
    }
    public void removeParallelTask(Runnable task) {
        if (task == null) {
            throw new NullPointerException("Parallel task cannot be null");
        }

        ThreadPoolExecutor executor;
        synchronized (lock) {
            executor = threadPoolExecutor;
            if (executor == null || executor.isShutdown()) {
                throw new IllegalStateException("ThreadPool has been shutdown");
            }
        }
        executor.remove(task);
        logPoolStatus(executor);
    }
    /**
     * 添加串行任务
     * @param task
     */
    public void addSerialTask(Runnable task) {
        if (task == null) {
            throw new NullPointerException("Serial task cannot be null");
        }

        synchronized (lock) {
            if (threadPoolExecutor == null || threadPoolExecutor.isShutdown()) {
                throw new IllegalStateException("ThreadPool has been shutdown");
            }

            serialTaskQueue.offer(() -> {
                try {
                    task.run();
                } finally {
                    synchronized (lock) {
                        activeTask = null;
                        scheduleNextSerialTask();
                    }
                }
            });

            if (activeTask == null) {
                scheduleNextSerialTask();
            }
        }
    }

    private void scheduleNextSerialTask() {
        synchronized (lock) {
            if (threadPoolExecutor == null || threadPoolExecutor.isShutdown()) {
                return;
            }

            Runnable nextTask = serialTaskQueue.poll();
            if (nextTask != null) {
                activeTask = nextTask;
                threadPoolExecutor.execute(nextTask);
            }
        }
    }

    public void stopThreadPool() {
        ThreadPoolExecutor executor;
        synchronized (lock) {
            executor = threadPoolExecutor;
            threadPoolExecutor = null;
            activeTask = null;
            serialTaskQueue.clear();
            workQueue.clear();
        }

        if (executor != null) {
            executor.shutdownNow();
            try {
                if (!executor.awaitTermination(500, TimeUnit.MILLISECONDS)) {
                    executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                executor.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }

    public boolean isTaskActive() {
        synchronized (lock) {
            return activeTask != null;
        }
    }

    public int getPendingParallelTasks() {
        synchronized (lock) {
            return workQueue.size();
        }
    }

    public int getPendingSerialTasks() {
        synchronized (lock) {
            return serialTaskQueue.size();
        }
    }

    public int getActiveThreadCount() {
        synchronized (lock) {
            return threadPoolExecutor != null ? threadPoolExecutor.getActiveCount() : 0;
        }
    }

    @SuppressLint("DefaultLocale")
    private void logPoolStatus(ThreadPoolExecutor executor) {
        LogUtil.e(String.format("Pool status: Active=%d, Queue=%d, Completed=%d%n",
                executor.getActiveCount(),
                executor.getQueue().size(),
                executor.getCompletedTaskCount()));
    }
}
